#include <stdio.h>
#include <stdlib.h>
#include "cuda_info.hh"
#include "atlas.hh"
#include "space_object.hh"
#include "cuda_helper.h"

#define ATLAS_LENGTH 10
#define OBJECTS_LENGTH 40000

int main(void) {
	CudaInfo_Init();
	SpaceObjectAtlas *atlas = new SpaceObjectAtlas();

	SpaceObjectAtlas::SOA_Data* geometry_atlas = new SpaceObjectAtlas::SOA_Data[ATLAS_LENGTH];
	for(int i = 0; i < ATLAS_LENGTH; i++){
		geometry_atlas[i].id = i;
		geometry_atlas[i].sphereRadius = (i % 2) * 3;
		geometry_atlas[i].geomId = i;
	}

	atlas->setAtlas(geometry_atlas, ATLAS_LENGTH);
	free(geometry_atlas);

	atlas->calcSqrs();

	SpaceObject *objects = new SpaceObject(atlas);

	for(int i = 0; i < OBJECTS_LENGTH; i++){
		objects->AddObject(i * 3 + ((i % 3) * 2 - 1), 0, 0, 0, i % ATLAS_LENGTH);
	}

	objects->Prepare();
	CUDA_CALL(cudaThreadSynchronize());

	cudaEvent_t start, stop;
	cudaEventCreate(&start);
	cudaEventCreate(&stop);
	cudaEventRecord(start, 0);
	objects->Collide();
	cudaEventRecord(stop, 0);

	CUDA_CALL(cudaThreadSynchronize());
	CUDA_CALL(cudaGetLastError());

	float elapsedTime;
	CUDA_CALL(cudaEventElapsedTime(&elapsedTime, start, stop));
	printf("CUDA time: %3.1f ms\n", elapsedTime);

	printf("Atlas:\n");
	geometry_atlas = atlas->getHost();
	for(int i = 0; i < atlas->getCount(); i++){
		printf("%d: %f\n", i, geometry_atlas[i].sphereRadiusSqr);
	}
	printf("\nObjects: \n");
	SpaceObject::SO_Data *obj = objects->getObjects();
	for(int i = 0; i < 20; i++){
		printf("%d: (%f, %f, %f): %f - %s with %d\n", i, obj[i].x, obj[i].y, obj[i].z, geometry_atlas[obj[i].atlas_id].sphereRadius, obj[i].collide ? "true" : "false", obj[i].collide_id);
	}

	CUDA_CALL(cudaDeviceReset());

	return 0;
}
